import { v4 as uuid } from "uuid";
import { Response } from 'express'
import {ISqlInsert, IPromiseCommonResponse, ISqlUpdate, tokenParams} from '../../global'
import hashMethod from "../utils/hashMethod";
import {
    userAddDao,
    userCountDao,
    userResetDao,
    passwordLoginDao,
    IUser,
    codeLoginDao,
    tokenInfoDao, changeNameDao, userStateDao
} from '../dao/userDao'
import {commonResponse} from "../utils/commonResponse";
import RedisServer from "../utils/redis";
import {generateToken, parseToken, IParseToken} from "../utils/jwt";

// 新增用户
export const userAddService = async (res: Response, mode: string, code: string, email: string) => {
    await commonResponse<IPromiseCommonResponse<{ msg: string } | ISqlInsert>, { msg: string }>(res, async () => {
        const count = await userCountDao([email])
        if (count[0].count === 0) {
            const redisData = await RedisServer.redisGet(`code:${email}`)
            if (redisData) {
                const redisCodeMode = JSON.parse(redisData)
                 return redisCodeMode.code === code && redisCodeMode.mode === mode ?  Promise.resolve({ code: 200, data: await userAddDao([uuid(), email, hashMethod(email)]) }) : Promise.resolve({ code: 500, data: { msg: '验证码错误' } })
            } else {
                return Promise.resolve({ code: 500, data: { msg: '请先获取验证码' }})
            }
        } else {
            return Promise.resolve({ code: 500, data: { msg: '该账号邮箱已存在' } })
        }
    })
}

// 重置密码
export const userResetService = async (res: Response, mode: string, code: string, email: string, password: string) => {
    await commonResponse<IPromiseCommonResponse<{ msg: string } | ISqlUpdate>, { msg: string }>(res, async () => {
        const redisData = await RedisServer.redisGet(`code:${email}`)
        if (redisData) {
            const redisCodeMode = JSON.parse(redisData)
            return redisCodeMode.code === code && redisCodeMode.mode === mode ?  Promise.resolve({ code: 200, data: await userResetDao([password, email]) }) : Promise.resolve({ code: 500, data: { msg: '验证码错误' } })
        } else {
            return Promise.resolve({ code: 500, data: { msg: '请先获取验证码' }})
        }
    })
}
interface ILoginResponse {
    msg: string
    token: string
    info: IUser
}
const loginResult = async (userList: Array<IUser>, email: string) => {
    return userList.length === 0 ?
        Promise.resolve({ code: 500, data: { msg: '账号或密码错误' }}) :
        Promise.resolve({
            code: 200,
            data: {
                msg: '登录成功',
                info: userList[0],
                token: await generateToken<tokenParams>({ email, date: (new Date()).getTime(), userUID: userList[0].userUID, secretKey: userList[0].secretKey, role: userList[0].role }, email)
            }
        })
}
/*
* 密码登录
* state: 用户状态 0 禁用 1 正常
* */
export const passwordLoginService = async (res: Response, email: string, password: string) => {
    await commonResponse<IPromiseCommonResponse<{ msg: string }>, { msg: string } | ILoginResponse>(res, async () => {
        const state = await userStateDao([email])
        if (state.length !== 0) {
            if(Number(state[0].state) === 1) {
                const userList: Array<IUser> = await passwordLoginDao([email, password])
                return await loginResult(userList, email)
            } else {
                return Promise.resolve({ code: 500, data: { msg: '账号已被禁用' } })
            }
        } else {
            return Promise.resolve({ code: 500, data: { msg: '用户不存在' } })
        }
    })
}

// 验证码登录
export const codeLoginService = async (res: Response, email: string, code: string, mode: string) => {
    await commonResponse<IPromiseCommonResponse<{ msg: string }>, { msg: string } | ILoginResponse>(res,  async () => {
        const redisData = await RedisServer.redisGet(`code:${email}`)
        if (redisData) {
            const redisCodeMode = JSON.parse(redisData)
            if (redisCodeMode.code === code && redisCodeMode.mode === mode) {
                const state = await userStateDao([email])
                if (state.length !== 0) {
                    if(Number(state[0].state) === 1) {
                        const userList: Array<IUser> = await codeLoginDao([email])
                        return await loginResult(userList, email)
                    } else {
                        return Promise.resolve({ code: 500, data: { msg: '账号已被禁用' } })
                    }
                } else {
                    return Promise.resolve({ code: 500, data: { msg: '用户不存在' } })
                }
            } else {
                return Promise.resolve({ code: 500, data: { msg: '验证码错误' } })
            }
        } else {
            return Promise.resolve({ code: 500, data: { msg: '请先获取验证码' }})
        }
    })
}

// 通过token获取信息
export const tokenInfoService = async (res: Response, token: string | string[] | undefined) => {
    await commonResponse<IPromiseCommonResponse<IUser | { msg: string }>, IUser | { msg: string }>(res,  async () => {
        const params = parseToken(token as string)
        const redisToken = await RedisServer.redisGet(`token:${(params as tokenParams).email}`)
        return redisToken && redisToken === token ? Promise.resolve({ code: 200, data: (await tokenInfoDao([(params as tokenParams).email]))[0] }) : Promise.resolve({ code: 500, data: { msg: '异常' } })
        // if (params.code === 200) {
        //     const count = await userCountDao([(params as tokenParams).email])
        //     if (count[0].count === 0) {
        //         return Promise.resolve({ code: 500, data: { msg: '用户不存在' } })
        //     } else {
        //         const redisToken = await RedisServer.redisGet(`token:${(params as tokenParams).email}`)
        //         return redisToken && redisToken === token ? Promise.resolve({ code: 200, data: params }) : Promise.resolve({ code: 500, data: { msg: '异常' } })
        //     }
        // }
        // return Promise.resolve({ code: 500, data: { msg: '异常' } })
    })
}

// 修改用户名
export const changeNameService = async (res: Response, name: string, email: string) => {
    await commonResponse<IPromiseCommonResponse<ISqlUpdate | { msg: string }>, { msg: string }>(res,  async () => {
        return Promise.resolve({ code: 200, data: await changeNameDao([name, email]) })
    })
}